using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;

using UnityEditor;

using UnityEngine;

namespace QFramework
{
    [CreateAssetMenu(menuName="@ItemKit/Create Item Database")]
    public class ItemDatabase : ScriptableObject
    {
        [DisplayLabel("命名空间：")]
        public string Namespace = "QFramework.Example";
        public List<Item> Items;

    }
    
    #if UNITY_EDITOR
    
    [UnityEditor.CustomEditor(typeof(ItemDatabase))]
    public class ItemDatabaseEditor:UnityEditor.Editor
    {
        private SerializedProperty mItems;
        
        public class ItemEditorObj
        {
            public bool Flodout
            {
                get
                {
                    return EditorPrefs.GetBool(Item.GetName+"_foldout",true);
                }
                set
                {
                    EditorPrefs.SetBool(Item.GetName+"_foldout",value);
                }
            }

            public Editor Editor = null;
            public Item Item = null;
        }

        private List<ItemEditorObj> mItemsEditors=new List<ItemEditorObj>();
        private void OnEnable()
        { 
            mItems = serializedObject.FindProperty("Items");
            
            RefreshItemEditors();
        }

        void RefreshItemEditors()
        { 
            mItemsEditors.Clear();
            for (int i = 0; i < mItems.arraySize; i++)
            {
                var itemSo = mItems.GetArrayElementAtIndex(i);
                var editor = CreateEditor(itemSo.objectReferenceValue);
                mItemsEditors.Add(new ItemEditorObj()
                {
                    Editor = editor,
                    Item = itemSo.objectReferenceValue as Item,
                });
            }
        }

        private string mSearchKey = "";
        private FluentGUIStyle mHeader = FluentGUIStyle.Label().FontBold();

        private Queue<Action> mActionQueue = new Queue<Action>();
        
        public override void OnInspectorGUI()
        {
            //base.OnInspectorGUI();
            serializedObject.Update();
            
            GUILayout.BeginVertical("box");
            serializedObject.DrawProperties(false,0,"Items");

            if (mItems.arraySize!=mItemsEditors.Count)
            {
                RefreshItemEditors();
            }
            
            if (GUILayout.Button("生成代码"))
            { 
                // 拿到项目里所有的ItemConfig
                // target指的是编辑器对应的脚本，也就是ItemDatabase
                var itemDB = target as ItemDatabase;

                var filePath = AssetDatabase.GetAssetPath(target).GetFolderPath()+"/Items.cs";

                var rootCode = new RootCode()
                    .Using("UnityEngine")
                    .Using("QFramework")
                    .EmptyLine()
                    .Namespace(itemDB.Namespace, ns =>
                    {
                        ns.Class("Items", String.Empty, false, false, c =>
                        {
                            foreach (var itemConfig in itemDB.Items)
                            {
                                c.Custom($"public static IItem {itemConfig.Key} => ItemKit.ItemByKey[\"{itemConfig.Key}\"];");
                                c.Custom($"public static string {itemConfig.Key}_key = \"{itemConfig.Key}\";");
                            }
                        });
                    });

                //var fileWriter = File.CreateText(filePath);
                //var codeWriter = new FileCodeWriter(fileWriter);
                //rootCode.Gen(codeWriter);
                //fileWriter.Close();
                // 和下面的效果一样
            
                using var fileWriter = File.CreateText(filePath);
                var codeWriter = new FileCodeWriter(fileWriter);
                rootCode.Gen(codeWriter);
            
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }
            GUILayout.EndVertical();

            
            EditorGUILayout.Separator();
            GUILayout.Label("物品列表：",mHeader);
            GUILayout.BeginHorizontal();
            GUILayout.Label("搜索：",GUILayout.Width(40));
            mSearchKey = EditorGUILayout.TextField(mSearchKey);
            GUILayout.EndHorizontal();
            
            for (var i = 0; i < mItemsEditors.Count; i++)
            {
                var itemEditor = mItemsEditors[i];

                if (!itemEditor.Item.Name.Contains(mSearchKey)&&!itemEditor.Item.Key.Contains(mSearchKey))
                {
                    continue;
                }
                
                GUILayout.BeginVertical("box");
                GUILayout.BeginHorizontal();
                itemEditor.Flodout = EditorGUILayout.Foldout(itemEditor.Flodout, itemEditor.Item.GetName);
                //item.DrawProperty();

                //var itemObj = itemEditor.ItemSo;
                // var itemSo = new SerializedObject(itemEditor.Item);
                // itemSo.Update();
                
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("-"))
                {
                    if (EditorUtility.DisplayDialog("删除物品", "确定要删除吗？", "确定", "取消"))
                    {
                        var index = i;
                        mActionQueue.Enqueue(() =>
                        {
                            //EditorUtility.DisplayDialog("删除物品", "确定要删除吗？", "确定", "取消");
                            var arrayElement = mItems.GetArrayElementAtIndex(index);
                            AssetDatabase.RemoveObjectFromAsset(arrayElement.objectReferenceValue);
                            mItems.DeleteArrayElementAtIndex(index);
                            serializedObject.ApplyModifiedPropertiesWithoutUndo();
                            // AssetDatabase.SaveAssets();
                            // AssetDatabase.Refresh();
                        
                            //RefreshItemEditors();
                        });
                    }
                }
                GUILayout.EndHorizontal();
                if (itemEditor.Flodout)
                {
                    itemEditor.Editor.OnInspectorGUI();
                    //Editor.CreateEditor(itemObj).OnInspectorGUI();
                }

                //itemSo.ApplyModifiedPropertiesWithoutUndo();
                GUILayout.EndVertical();
            }
            
            if (GUILayout.Button("创建物品"))
            {
                mActionQueue.Enqueue(() =>
                {
                    var item = Item.CreateInstance<Item>();
                    item.name = nameof(Item);
                    item.Name = "新物品";
                    item.Key = "item_key";
                    AssetDatabase.AddObjectToAsset(item,target);
                    mItems.InsertArrayElementAtIndex(mItems.arraySize);

                    serializedObject.ApplyModifiedPropertiesWithoutUndo();
                    
                    var arrayElement = mItems.GetArrayElementAtIndex(mItems.arraySize - 1);
                    arrayElement.objectReferenceValue = item;
                
                    serializedObject.ApplyModifiedPropertiesWithoutUndo();
                    //AssetDatabase.SaveAssets();
                    //AssetDatabase.Refresh();
                    //RefreshItemEditors();
                });
            }
            //Debug.Log(mItems.arraySize);

            if (mActionQueue.Count>0)
            {
                mActionQueue.Dequeue().Invoke();
            }
            
            serializedObject.ApplyModifiedPropertiesWithoutUndo();
        }
    }
    
    #endif
}
